/**
 * 通用工具函数
 */

/**
 * 深拷贝
 * @param {*} obj 需要深拷贝的对象
 * @returns {*} 深拷贝后的对象
 */
export function deepClone(obj) {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }

  if (obj instanceof Date) {
    return new Date(obj);
  }

  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }

  if (Array.isArray(obj)) {
    return obj.map((item) => deepClone(item));
  }

  const result = {};

  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      result[key] = deepClone(obj[key]);
    }
  }

  return result;
}

/**
 * 节流函数
 * @param {Function} fn 需要节流的函数
 * @param {Number} delay 延迟时间，单位毫秒
 * @returns {Function} 节流后的函数
 */
export function throttle(fn, delay = 500) {
  let timer = null;
  let lastTime = 0;

  return function (...args) {
    const context = this;
    const now = Date.now();

    if (now - lastTime >= delay) {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }

      fn.apply(context, args);
      lastTime = now;
    } else if (!timer) {
      timer = setTimeout(() => {
        fn.apply(context, args);
        lastTime = Date.now();
        timer = null;
      }, delay - (now - lastTime));
    }
  };
}

/**
 * 防抖函数
 * @param {Function} fn 需要防抖的函数
 * @param {Number} delay 延迟时间，单位毫秒
 * @returns {Function} 防抖后的函数
 */
export function debounce(fn, delay = 500) {
  let timer = null;

  return function (...args) {
    const context = this;

    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(context, args);
      timer = null;
    }, delay);
  };
}

/**
 * 随机生成字符串
 * @param {Number} length 字符串长度
 * @returns {String} 随机字符串
 */
export function randomString(length = 16) {
  const chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";

  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }

  return result;
}

/**
 * 生成UUID
 * @returns {String} UUID
 */
export function generateUUID() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0;
    const v = c === "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

/**
 * 金额格式化
 * @param {Number} num 金额
 * @param {Number} precision 小数位数
 * @returns {String} 格式化后的金额
 */
export function formatMoney(num, precision = 2) {
  if (isNaN(num)) return "0.00";

  return Number(num)
    .toFixed(precision)
    .replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

/**
 * 获取屏幕安全区域
 * @returns {Object} 安全区域信息
 */
export function getSafeArea() {
  const safeArea = uni.getSystemInfoSync().safeArea || {};
  const statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0;

  return {
    top: safeArea.top || statusBarHeight || 0,
    right: safeArea.right || 0,
    bottom: safeArea.bottom || 0,
    left: safeArea.left || 0,
    width: safeArea.width || uni.getSystemInfoSync().windowWidth || 0,
    height:
      safeArea.height ||
      uni.getSystemInfoSync().windowHeight - statusBarHeight ||
      0,
  };
}

/**
 * 复制文本
 * @param {String} text 需要复制的文本
 * @param {String} msg 复制成功提示文本
 * @returns {Promise} Promise对象
 */
export function copyText(text, msg = "复制成功") {
  return new Promise((resolve, reject) => {
    uni.setClipboardData({
      data: text,
      success: () => {
        if (msg) {
          uni.showToast({
            title: msg,
            icon: "none",
          });
        }
        resolve(true);
      },
      fail: (err) => {
        reject(err);
      },
    });
  });
}

/**
 * 打开地图位置
 * @param {Object} options 配置项
 * @returns {Promise} Promise对象
 */
export function openLocation(options) {
  return new Promise((resolve, reject) => {
    uni.openLocation({
      ...options,
      success: resolve,
      fail: reject,
    });
  });
}

/**
 * 将编码后的八进制的emoji表情重新解码成十六进制的表情字符
 */
export function entitiesToUtf16(str) {
  return str.replace(/&#(\d+);/g, function (match, dec) {
    let H = Math.floor((dec - 65536) / 1024) + 55296;
    let L = (Math.floor(dec - 65536) % 1024) + 56320;
    return String.fromCharCode(H, L);
  });
}

/**
 * 检测登录状态并决定是否跳转
 * @param {Object} options 配置项
 * @param {String} options.redirectUrl 需要跳转的目标页面路径
 * @param {Boolean} options.force 是否强制要求登录
 * @param {String} options.loginUrl 登录页面路径，默认为'/pages/login/index'
 * @param {Function} options.success 已登录时的回调函数
 * @param {Function} options.fail 未登录时的回调函数
 * @returns {Boolean} 是否已登录
 */
export function checkLogin(options = {}) {
  const {
    redirectUrl = "",
    force = true,
    loginUrl = "/pages/login/index",
    success,
    fail,
  } = options;

  // 从Vuex获取登录状态
  const store = getApp().$vm.$store;
  const isLoggedIn = store.getters["user/isLoggedIn"];

  if (isLoggedIn) {
    // 已登录
    typeof success === "function" && success();

    // 如果有重定向URL，则跳转
    if (redirectUrl) {
      uni.navigateTo({
        url: redirectUrl,
        fail: (err) => {
          console.error("页面跳转失败:", err);
          uni.showToast({
            title: "页面跳转失败",
            icon: "none",
          });
        },
      });
    }

    return true;
  } else {
    // 未登录
    typeof fail === "function" && fail();

    // 强制登录
    if (force) {
      // 构建登录后的重定向路径
      let redirectPath = "";
      if (redirectUrl) {
        redirectPath = `?redirect=${encodeURIComponent(redirectUrl)}`;
      }

      uni.navigateTo({
        url: `${loginUrl}${redirectPath}`,
        fail: (err) => {
          console.error("登录页面跳转失败:", err);
          uni.showToast({
            title: "登录页面跳转失败",
            icon: "none",
          });
        },
      });
    }

    return false;
  }
}
